package com.statistics.word.impl.excel;


import com.statistics.annotation.FieldAlias;
import com.statistics.entity.BaseEntity;
import com.statistics.word.Word;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;

/**
 * @author HeWei123
 */
@Slf4j
public class ExcelPoiWordAnalysis<T extends BaseEntity> implements Word {


    protected Class<?> tClass = WordHelper.currentModelClass(getClass());

    @Override
    public List<T> analysis(MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) {
            // 不区分版本
            Workbook workBook = new XSSFWorkbook(inputStream);
            return taxWorkBook(workBook);
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            throw new RuntimeException("-1");
        }
    }


    /**
     * 解析税务/报验登记excel
     * 解析workBook
     * 获取Row对象获取行级数据
     * 使用poi空值策略对空格进行处理  MissingCellPolicy.RETURN_BLANK_AS_NULL 返回空值或者null
     * 存储第一行表头数据 去除第一个单元格
     * 添加返回的对象进数组中解析成对象
     *
     * @param workBook
     */
    protected List<T> taxWorkBook(Workbook workBook) {
        // 获取第一个sheet
        Sheet sheet = workBook.getSheetAt(0);
        // 用于存储表头的集合
        List<String> list = new LinkedList<>();
        // 用于存储所有数据的集合
        List<T> swdjList = new ArrayList<>();
        // 行数变量
        int tempInt = 0;
        for (Row row : sheet) {
            // 用于存储每行数据的集合
            Map<String, Object> map = new LinkedHashMap<>();
            //行的单元格数
            int i = 0;
            for (int i1 = 0; i1 < row.getLastCellNum(); i1++) {
                if (tempInt == 0 && i > 0 && row.getCell(i).getCellType() == CellType.BLANK) {
                    break;
                }
                //二期改读取标题头，il为0
                Cell cell = row.getCell(i1, Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
                if (tempInt == 0 && i >= 0) {
                    //表头存list里
                    list.add(cell.getRichStringCellValue().toString());
                }
                if (tempInt > 0 && i >= 0) {
                    if (null == cell) {
                        map.put(list.get(i), "");
                        i++;
                        continue;
                    }
                    WordHelper.addMapDate(cell, map, list, i);
                }
                i++;

            }
            if (tempInt > 0) {
                T transition = transition(map);
                swdjList.add(transition);
            }
            tempInt++;
        }
        return swdjList;
    }


    /**
     * 第一个<T> 表示返回的泛型类型 （可以是任何类型）
     * 第二个 T 返回 T 类型的数据
     * 第三个 T 表示限制参数类型为 T
     * <T> T 这个意思就是  我不确定我返回的类型是什么，但是我肯定有一个返回的类型
     * Class<T> 装载一个对象类型，可以是任何类型。
     *
     * @param map 存储的对象集合
     * @return class<T>指返回一个对象
     */

    protected T transition(Map<String, Object> map) {
        Object o1 = null;
        Boolean flag = true;
        try {
            try {
                o1 = tClass.newInstance();
                Iterator<String> iterator = map.keySet().iterator();
                while (iterator.hasNext() && flag) {
                    String next = iterator.next();
                    String fieldName = null;
                    boolean boo = true;
                    final Field[] fields = tClass.getDeclaredFields();
                    for (Field field : fields) {
                        if (boo) {
                            final Annotation[] declaredAnnotations = field.getDeclaredAnnotations();
                            for (Annotation annotation : declaredAnnotations) {
                                if (annotation instanceof FieldAlias) {
                                    final boolean equals = ((FieldAlias) annotation).name().equals(next);
                                    if (equals) {
                                        fieldName = field.getName();
                                        boo = false;
                                    }
                                }
                            }
                        }
                    }
                    if (boo) {
                        fieldName =  next;
                    }
                    Field field = tClass.getDeclaredField(fieldName);
                    if (null != field) {
                        WordHelper.replaceClass(field.getGenericType(), map, next);
                        Object obj = map.get(next);
                        String method = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                        tClass.getDeclaredMethod(method, field.getType()).invoke(o1, obj);
                    }
                }
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
                throw new RuntimeException("excel文件错误");
            }
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            e.printStackTrace();
            log.error(this.getClass().getName() + "数据解析失败" + e.getMessage());
            throw new RuntimeException("-1");
        }
        return (T) o1;
    }
}
